package com.conduit.agent;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.conduit.comnands.Command;
import com.conduit.comnands.GetRegistryValueCommand;
import com.conduit.comnands.InstallCommand;
import com.conduit.comnands.UndefinedCommand;
import com.conduit.comnands.ValidateRegistryCommand;
import com.conduit.enums.ResultCode;

public class Agent {

	HashMap<String, Command> commands = new HashMap<String, Command>();
	HashMap<String, String> runProperties = new HashMap<String, String>();
	Command currentCommand;

	public Agent() {
		commands.put("install", new InstallCommand());
		commands.put("get registry value", new GetRegistryValueCommand());
		commands.put("validate registry", new ValidateRegistryCommand());
	}

	public void executeCommand(String command) {
		String commandName = command.split("\\s{2,}")[0].toLowerCase();
		try {
			currentCommand = commands.get(commandName);
			command = replaceArgumentsPlaceHolders(command);
			currentCommand.executeWithArgs(command);
			if (currentCommand.isReturnValue()) {
				runProperties.put(currentCommand.getResult().split(" is a ")[0], currentCommand.getResult().split(" is a ")[1]);
			}
		} catch (NullPointerException e) {
			currentCommand = new UndefinedCommand();
			currentCommand.setResult("Could not find command name");
			currentCommand.setResultCode(ResultCode.Error);
		}
	}

	public void report(int commandIndex, String machineIP) {
		System.out.println(String.format("Command #%d on machine %s: %s Result: %s Result Code: %d", commandIndex,
				machineIP, currentCommand.getCommandName(), currentCommand.getResult(), currentCommand.getResultCode()
						.ordinal()));
	}

	public String replaceArgumentsPlaceHolders(String command) {
		Matcher matcher = Pattern.compile(".*?\\$\\{(.*?)\\}").matcher(command);
		while (matcher.find()) {
			String value = runProperties.get(matcher.group(1));
			if (value != null) {
				command = command.replace("${" + matcher.group(1) + "}", value);
			} //TODO add a report if the parameter was not found.
		}
		return command;
	}

}
